import React, { useState, useEffect } from 'react';
const debug = require('debug')('setStateTime');

let count2 = 0;
/**
 * 参考 [React的setState执行机制](https://www.cnblogs.com/mengff/p/9611614.html)
 */
export default function UseStateInspect() {
  count2 += 1;
  const count = count2;
  const [state, setState] = useState(() => ({ a: 1, b: 2 } as any));
  // 事件中同步调用范例
  const change1 = () => {
    debug('in change1 count=%d', count);
    setState({ c: 3 });
    setState({ d: 4 });
    // 结果是最后 state = {d: 4}，而不像某些文档说的如同 Object.assign (this.setState是这样的)
  }
  const change2 = () => {
    // 经测试，react 事件回调函数中的 setState, reducer 是同步执行的
    setState((v: any) => ({ ...v, c: 3 }));
    setState((v: any) => {
      let count2 = count;
      debug('in change2 in reducer count=%d', count);
      return { ...v, d: 4 }
    });
    // 这里比上面 setState 中的 reducer 还要早执行，就是被收集往后才调度了
    debug('in change2 after reducer count=%d', count);
    // 结果是最后 state = {d: 4}，而不像某些文档说的如同 Object.assign (this.setState是这样的)
  }
  useEffect(() => {
    debug('useEffect start count=%d', count);
    return () => {
      debug('useEffect dispose count=%d', count);
    }
  })
  debug('before render count=%d', count);
  return (
    <div>
      <button onClick={change1}>change by value</button>
      <button onClick={change2}>change by reducer</button>
      <pre>{JSON.stringify(state, null, 2)}</pre>
    </div>
  )
}
